classdef MessageService < handle
    % MESSAGESERVICE 消息管理服务
    % 基于DO-178规则第4条（架构分离原则）设计
    % 负责消息的构建、累积、格式化和颜色管理
    %
    % 功能：
    %   - 消息累积和格式化
    %   - 消息级别管理（info/warning/error/success）
    %   - 颜色映射（从级别到RGB值，GUI只负责显示）
    %   - 时间戳管理
    %   - 支持单条和多条消息管理
    %
    % 设计原则：
    %   - 颜色逻辑在Service中处理，GUI只负责显示
    %   - 明确的消息级别，便于调试和追溯
    %   - 支持DO-178的可追溯性要求
    %
    % 使用示例：
    %   % 方式1：快速累积消息（兼容旧代码）
    %   msg = MessageService.accumulate(msg1, msg2);
    %   msg = MessageService.accumulate(msg1, msg2, 'Separator', '; ');
    %   
    %   % 方式2：创建结构化消息
    %   msgObj = MessageService.create('操作成功', 'Level', 'success');
    %   msgObj = MessageService.create('发现警告', 'Level', 'warning');
    %   
    %   % 方式3：使用MessageBuilder累积多条消息
    %   builder = MessageService.createBuilder();
    %   builder.add('步骤1完成', 'info');
    %   builder.add('步骤2有警告', 'warning');
    %   builder.add('步骤3成功', 'success');
    %   result = builder.build();
    %   
    %   % GUI中使用
    %   app.MessagesTextArea.Value = result.text;
    %   app.MessagesTextArea.FontColor = result.color;
    %
    % 作者: MBD Platform Team
    % 日期: 2025-10-14
    % 遵循DO-178标准
    
    properties (Constant)
        % 消息级别定义
        LEVEL_INFO = 'info';
        LEVEL_WARNING = 'warning';
        LEVEL_ERROR = 'error';
        LEVEL_SUCCESS = 'success';
        
        % 颜色映射 [R, G, B]
        COLOR_INFO = [0, 0, 0];           % 黑色
        COLOR_WARNING = [0.93, 0.69, 0.13]; % 橙色
        COLOR_ERROR = [1.0, 0.0, 0.0];    % 红色
        COLOR_SUCCESS = [0.0, 0.5, 0.0];  % 深绿色（更适合阅读）
        COLOR_DEFAULT = [0, 0, 0];        % 默认黑色
    end
    
    methods (Static)
        
        %% ==================== 快速消息累积（兼容旧代码）====================
        
        function msg = accumulate(msg1, msg2, varargin)
            % ACCUMULATE 累积两个消息字符串（静态方法，兼容旧代码）
            % 
            % 输入参数:
            %   msg1 - 第一个消息（字符串、数字或逻辑值）
            %   msg2 - 第二个消息（字符串、数字或逻辑值）
            %   varargin - 可选参数（Name-Value pairs）
            %     'Separator' - 分隔符（默认：newline）
            % 
            % 输出参数:
            %   msg - 累积后的消息字符串
            %
            % 示例：
            %   msg = MessageService.accumulate('消息1', '消息2');
            %   msg = MessageService.accumulate('消息1', '消息2', 'Separator', '; ');
            
            % 参数解析
            p = inputParser;
            addParameter(p, 'Separator', newline, @(x) ischar(x) || isstring(x));
            parse(p, varargin{:});
            separator = char(p.Results.Separator);
            
            % 转换为字符串
            msg1 = MessageService.convertToChar(msg1);
            msg2 = MessageService.convertToChar(msg2);
            
            % 累积逻辑
            if isempty(msg1)
                msg = msg2;
            elseif isempty(msg2)
                msg = msg1;
            else
                msg = [msg1, separator, msg2];
            end
        end
        
        %% ==================== 结构化消息创建 ====================
        
        function msgStruct = create(text, varargin)
            % CREATE 创建结构化消息对象
            % 
            % 输入参数:
            %   text - 消息文本
            %   varargin - 可选参数（Name-Value pairs）
            %     'Level' - 消息级别（'info'/'warning'/'error'/'success'）
            %     'Timestamp' - 是否添加时间戳（默认：false）
            %     'TimestampFormat' - 时间戳格式（默认：'yyyy-MM-dd HH:mm:ss'）
            % 
            % 输出参数:
            %   msgStruct - 消息结构体
            %     .text - 消息文本（可能包含时间戳）
            %     .level - 消息级别
            %     .color - RGB颜色值 [R, G, B]
            %     .timestamp - 时间戳（datetime对象）
            %
            % 示例：
            %   msg = MessageService.create('操作成功', 'Level', 'success');
            %   msg = MessageService.create('操作失败', 'Level', 'error', 'Timestamp', true);
            
            % 参数解析
            p = inputParser;
            addParameter(p, 'Level', MessageService.LEVEL_INFO, ...
                @(x) ismember(x, {MessageService.LEVEL_INFO, ...
                                  MessageService.LEVEL_WARNING, ...
                                  MessageService.LEVEL_ERROR, ...
                                  MessageService.LEVEL_SUCCESS}));
            addParameter(p, 'Timestamp', false, @islogical);
            addParameter(p, 'TimestampFormat', 'yyyy-MM-dd HH:mm:ss', @ischar);
            parse(p, varargin{:});
            
            level = p.Results.Level;
            addTimestamp = p.Results.Timestamp;
            timestampFormat = p.Results.TimestampFormat;
            
            % 创建消息结构
            msgStruct = struct();
            msgStruct.level = level;
            msgStruct.color = MessageService.getLevelColor(level);
            msgStruct.timestamp = datetime('now');
            
            % 处理文本
            text = MessageService.convertToChar(text);
            if addTimestamp
                timestampStr = char(datetime('now'), timestampFormat);
                msgStruct.text = sprintf('[%s] %s', timestampStr, text);
            else
                msgStruct.text = text;
            end
        end
        
        %% ==================== 消息构建器工厂 ====================
        
        function builder = createBuilder(varargin)
            % CREATEBUILDER 创建消息构建器（用于累积多条消息）
            % 
            % 输入参数:
            %   varargin - 可选参数（Name-Value pairs）
            %     'Separator' - 消息分隔符（默认：newline）
            %     'TimestampFormat' - 时间戳格式（默认：'yyyy-MM-dd HH:mm:ss'）
            %     'IncludeTimestamp' - 是否包含时间戳（默认：false）
            % 
            % 输出参数:
            %   builder - MessageBuilder对象
            %
            % 示例：
            %   builder = MessageService.createBuilder();
            %   builder.add('步骤1完成', 'info');
            %   builder.add('步骤2有警告', 'warning');
            %   result = builder.build();
            
            builder = MessageBuilder(varargin{:});
        end
        
        %% ==================== 从消息文本自动推断级别 ====================
        
        function level = inferLevel(text)
            % INFERLEVEL 从消息文本自动推断级别
            % 
            % 输入参数:
            %   text - 消息文本
            % 
            % 输出参数:
            %   level - 推断的消息级别
            %
            % 规则：
            %   - 包含 'fail'/'error' → error
            %   - 包含 'warning'/'can not'/'can''t' → warning
            %   - 包含 'success'/'complete'/'done' → success
            %   - 其他 → info
            
            text = lower(MessageService.convertToChar(text));
            
            if contains(text, 'fail') || contains(text, 'error')
                level = MessageService.LEVEL_ERROR;
            elseif contains(text, 'warning') || contains(text, 'can not') || contains(text, 'can''t')
                level = MessageService.LEVEL_WARNING;
            elseif contains(text, 'success') || contains(text, 'complete') || contains(text, 'done')
                level = MessageService.LEVEL_SUCCESS;
            else
                level = MessageService.LEVEL_INFO;
            end
        end
        
        %% ==================== 颜色管理 ====================
        
        function color = getLevelColor(level)
            % GETLEVELCOLOR 获取级别对应的颜色
            % 
            % 输入参数:
            %   level - 消息级别
            % 
            % 输出参数:
            %   color - RGB颜色值 [R, G, B]
            
            switch level
                case MessageService.LEVEL_INFO
                    color = MessageService.COLOR_INFO;
                case MessageService.LEVEL_WARNING
                    color = MessageService.COLOR_WARNING;
                case MessageService.LEVEL_ERROR
                    color = MessageService.COLOR_ERROR;
                case MessageService.LEVEL_SUCCESS
                    color = MessageService.COLOR_SUCCESS;
                otherwise
                    color = MessageService.COLOR_DEFAULT;
            end
        end
        
        %% ==================== 工具方法 ====================
        
        function str = convertToChar(input)
            % CONVERTTOCHAR 将各种类型转换为字符数组
            % 
            % 支持的类型：char, string, numeric, logical
            
            if isempty(input)
                str = '';
            elseif ischar(input)
                str = input;
            elseif isstring(input)
                str = char(input);
            elseif isnumeric(input) || islogical(input)
                str = num2str(input);
            else
                % 尝试转换为字符串
                try
                    str = char(string(input));
                catch
                    str = '';
                end
            end
        end
        
    end
end

